package com.benjaminwan.read.free.views

import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.CompoundButton
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.core.view.setPadding
import com.airbnb.epoxy.CallbackProp
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.airbnb.epoxy.TextProp
import com.benjaminwan.read.free.R
import com.benjaminwan.read.free.model.enums.ItemType
import com.benjaminwan.read.free.utils.dp2px
import com.benjaminwan.read.free.utils.enable
import com.benjaminwan.read.free.utils.setCheckBoxEnable
import com.benjaminwan.read.free.utils.setSwitchEnable
import com.mywork.swipemenulayout.SwipeMenuItem
import com.mywork.swipemenulayout.SwipeMenuLayout
import com.mywork.swipemenulayout.SwipeMenuView
import com.xuexiang.xui.widget.textview.supertextview.SuperTextView

@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
class SuperTextViewItemView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    /*private val clickWatcher = SimpleClickWatcher { view ->
        if (view is SuperTextView) {
            onClickListener?.invoke(view)
        }
    }

    private val longClickListener = SimpleLongClickWatcher { view ->
        val ret = if (view is SuperTextView) {
            onLongClickListener?.invoke(view) ?: false
        } else {
            false
        }
        ret
    }*/

    private val contentLayout by lazy { findViewById<FrameLayout>(R.id.contentLayout) }
    private val swipeMenuLayout by lazy { findViewById<SwipeMenuLayout>(R.id.swipeMenuLayout) }
    private val swipeDirectionIV by lazy { findViewById<ImageView>(R.id.swipeDirectionIV) }
    private val indexTv by lazy { findViewById<TextView>(R.id.indexTv) }
    private val commonTextStv by lazy { findViewById<SuperTextView>(R.id.commonTextStv) }
    private val commonSwitchStv by lazy { findViewById<SuperTextView>(R.id.commonSwitchStv) }
    private val commonCheckBoxStv by lazy { findViewById<SuperTextView>(R.id.commonCheckBoxStv) }
    private val superTextViewContainer by lazy { findViewById<LinearLayout>(R.id.superTextViewContainer) }
    private val swipeContainerLayout by lazy { findViewById<LinearLayout>(R.id.swipeContainerLayout) }
    private val rightLayout by lazy { findViewById<SwipeMenuView>(R.id.rightLayout) }

    init {
        View.inflate(context, R.layout.rv_common_swipe_menu_item, this)
        LayoutInflater.from(this.context)
            .inflate(R.layout.rv_common_super_textview_item, this.contentLayout)
        swipeMenuLayout.onMenuRightOpenListener = {
            swipeDirectionIV.setImageResource(R.drawable.ic_swipe_right_black_24dp)
        }
        swipeMenuLayout.onMenuCloseListener = {
            swipeDirectionIV.setImageResource(R.drawable.ic_swipe_left_black_24dp)
        }
        /*commonTextStv.setOnClickListener(clickWatcher)
        commonSwitchStv.setOnClickListener(clickWatcher)
        commonTextStv.setOnLongClickListener(longClickListener)
        commonSwitchStv.setOnLongClickListener(longClickListener)*/
    }

    private var downX = 0
    private var downY = 0
    private var hasSwipeMenu = false

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (!hasSwipeMenu) {
            return super.dispatchTouchEvent(ev)
        }
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                downX = ev.x.toInt()
                downY = ev.y.toInt()
                parent?.requestDisallowInterceptTouchEvent(true)
            }

            MotionEvent.ACTION_MOVE -> {
                val moveX = ev.x.toInt()
                val moveY = ev.y.toInt()
                val diffX = moveX - downX
                val diffY = moveY - downY
                if (Math.abs(diffX) > Math.abs(diffY)) { // 当前是横向滑动, 不让父元素拦截
                    parent?.requestDisallowInterceptTouchEvent(true)
                } else {
                    parent?.requestDisallowInterceptTouchEvent(false)
                }
            }

            else -> {
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    @TextProp
    fun setHeader(content: CharSequence?) {
        if (content.isNullOrEmpty()) {
            indexTv.visibility = View.GONE
        } else {
            indexTv.visibility = View.VISIBLE
            indexTv.text = content
        }
    }

    @ModelProp
    fun setLeftTextColor(@ColorInt color: Int?) {
        color ?: return
        commonTextStv.setLeftTextColor(color)
        commonSwitchStv.setLeftTextColor(color)
        commonCheckBoxStv.setLeftTextColor(color)
    }

    @ModelProp
    fun setItemType(type: ItemType) {
        when (type) {
            ItemType.Switch -> {
                commonTextStv.visibility = View.GONE
                commonSwitchStv.visibility = View.VISIBLE
                commonCheckBoxStv.visibility = View.GONE
            }

            ItemType.Text -> {
                commonTextStv.visibility = View.VISIBLE
                commonSwitchStv.visibility = View.GONE
                commonCheckBoxStv.visibility = View.GONE
            }

            ItemType.CheckBox -> {
                commonTextStv.visibility = View.GONE
                commonSwitchStv.visibility = View.GONE
                commonCheckBoxStv.visibility = View.VISIBLE
            }
        }
    }

    @ModelProp
    fun setBorderWidthDp(padding: Int?) {
        if (padding == null) {
            superTextViewContainer.setPadding(0)
        } else {
            superTextViewContainer.setPadding(context.dp2px(padding))
        }
    }

    @ModelProp
    @JvmOverloads
    fun setItemHeightDp(height: Int = 40) {
        val heightPx = context.dp2px(height)
        val textSize = when (height) {
            in 0..5 -> 6f
            in 6..10 -> 8f
            in 10..15 -> 10f
            in 16..20 -> 11f
            in 21..25 -> 12f
            in 26..30 -> 13f
            in 31..35 -> 14f
            in 36..40 -> 15f
            in 41..45 -> 16f
            in 46..50 -> 17f
            else -> 18f
        }
        val params1 = commonTextStv.layoutParams
        params1.height = heightPx
        commonTextStv.layoutParams = params1
        commonTextStv.leftTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
        commonTextStv.centerTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
        commonTextStv.rightTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
        val params2 = commonSwitchStv.layoutParams
        params2.height = heightPx
        commonSwitchStv.layoutParams = params2
        commonSwitchStv.leftTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
        commonSwitchStv.centerTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
        val params3 = commonCheckBoxStv.layoutParams
        params3.height = heightPx
        commonCheckBoxStv.layoutParams = params3
        commonCheckBoxStv.leftTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
        commonCheckBoxStv.centerTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
    }

    @ModelProp
    fun setEnable(isEnable: Boolean?) {
        if (isEnable != null) {
            commonTextStv.enable = isEnable
            commonSwitchStv.enable = isEnable
            commonCheckBoxStv.enable = isEnable
        } else {
            commonTextStv.enable = true
            commonSwitchStv.enable = true
            commonCheckBoxStv.enable = true
        }
    }

    @ModelProp
    fun setCheckEnable(isEnable: Boolean?) {
        if (isEnable != null) {
            commonSwitchStv.setSwitchEnable(isEnable)
            commonCheckBoxStv.setCheckBoxEnable(isEnable)
        } else {
            commonSwitchStv.setSwitchEnable(true)
            commonCheckBoxStv.setCheckBoxEnable(true)
        }
    }

    @ModelProp
    fun setVisibility(visibility: Int?) {
        when (visibility) {
            null -> swipeContainerLayout.visibility = View.VISIBLE
            else -> swipeContainerLayout.visibility = visibility
        }
    }

    @ModelProp
    fun setTopDividerLineVisibility(visibility: Int?) {
        when (visibility) {
            null -> {
            }

            else -> {
                commonTextStv.setTopDividerLineVisibility(visibility)
                commonCheckBoxStv.setTopDividerLineVisibility(visibility)
                commonSwitchStv.setTopDividerLineVisibility(visibility)
            }
        }
    }

    @ModelProp
    fun setBottomDividerLineVisibility(visibility: Int?) {
        when (visibility) {
            null -> {
            }

            else -> {
                commonTextStv.setBottomDividerLineVisibility(visibility)
                commonCheckBoxStv.setBottomDividerLineVisibility(visibility)
                commonSwitchStv.setBottomDividerLineVisibility(visibility)
            }
        }
    }

    @ModelProp
    fun setIsChecked(isChecked: Boolean?) {
        isChecked ?: return
        commonSwitchStv.setSwitchIsChecked(isChecked, true)
        commonCheckBoxStv.setCheckBoxChecked(isChecked, true)
    }

    @TextProp
    fun setLeftText(content: CharSequence?) {
        commonTextStv.setLeftString(content ?: "")
        commonSwitchStv.setLeftString(content ?: "")
        commonCheckBoxStv.setLeftString(content ?: "")
    }

    @TextProp
    fun setRightText(content: CharSequence?) {
        commonTextStv.setRightString(content ?: "")
    }

    @TextProp
    fun setCenterText(content: CharSequence?) {
        commonTextStv.setCenterString(content)
        commonSwitchStv.setCenterString(content)
        commonCheckBoxStv.setCenterString(content)
    }

    @CallbackProp
    fun onClickListener(listener: View.OnClickListener?) {
        listener ?: return
        commonTextStv.setOnClickListener(listener)
        commonSwitchStv.setOnClickListener(listener)
        commonCheckBoxStv.setOnClickListener(listener)
    }

    /*@set:CallbackProp
    var onClickListener: ((view: SuperTextView) -> Unit)? = null*/

    @CallbackProp
    fun onLongClickListener(listener: View.OnLongClickListener?) {
        listener ?: return
        commonTextStv.setOnLongClickListener(listener)
        commonSwitchStv.setOnLongClickListener(listener)
        commonCheckBoxStv.setOnLongClickListener(listener)
    }

    /*@set:CallbackProp
    var onLongClickListener: ((view: SuperTextView) -> Boolean)? = null*/

    @CallbackProp
    fun onCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener?) {
        commonSwitchStv.setSwitchCheckedChangeListener(listener)
        commonCheckBoxStv.setCheckBoxCheckedChangeListener(listener)
    }

    @ModelProp
    @JvmOverloads
    fun setRightMenu(rightMenu: List<SwipeMenuItem>? = null) {
        if (rightMenu == null || rightMenu.isEmpty()) {
            hasSwipeMenu = false
            rightLayout.removeAllViews()
            swipeMenuLayout.isCanRightSwipe = false
            swipeDirectionIV.visibility = View.GONE
            //superTextViewContainer.setPadding(0, 0, 0, 0)
        } else {
            hasSwipeMenu = true
            rightLayout.createMenu(rightMenu)
            swipeMenuLayout.isCanRightSwipe = true
            swipeDirectionIV.visibility = View.VISIBLE
            //superTextViewContainer.setPadding(2, 2, 2, 2)
        }
    }

    @CallbackProp
    fun onRightMenuClickListener(listener: ((swipeLayout: SwipeMenuLayout, item: SwipeMenuItem, view: SuperTextView) -> Unit)?) {
        rightLayout.setOnMenuItemClickListener { item ->
            listener?.invoke(
                swipeMenuLayout, item, if (commonTextStv.visibility == View.VISIBLE) {
                    commonTextStv
                } else if (commonSwitchStv.visibility == View.VISIBLE) {
                    commonSwitchStv
                } else if (commonCheckBoxStv.visibility == View.VISIBLE) {
                    commonCheckBoxStv
                } else {
                    commonTextStv
                }
            )
        }
    }
}